#include "Utils.hlsli"

cbuffer cbPerFrame : register (b0) { 
	float4x4 gViewProj;
};

cbuffer cbImmutable : register (b1) { 
    float4x4 gTexMatrix;
};

struct VSInput {    
	float3 mPosW : POSITION;
    float2 mTexC : TEXCOORD;
    
    // Instancing data
    float3 mQuadCenterPosW : QUADCENTERW;
    float3 mQuadVelW       : QUADVELW;
};

struct VSOutput {
    float4 mPosH : SV_POSITION;
    float3 mPosW : POSITION;
    float2 mTexC : TEXCOORD;
};

VSOutput main(in const VSInput input) {
	VSOutput output;
	
    // Rotate vertex position according
    // linear velocity vector
	const float scalingFactor = 5.0f;
    const float4 vertexPosW =  float4(input.mPosW.x * scalingFactor, 
									  input.mPosW.y,
									  input.mPosW.z * scalingFactor, 
									  1.0f);
    float4 newVertexPosW = vertexPosW;
    if (!areEquals(length(input.mQuadVelW), 0.0f))  {
        float4x4 rotation;
        const float3 quadVelW = normalize(input.mQuadVelW);
        rotationAroundY(quadVelW, rotation);
        newVertexPosW = mul(newVertexPosW, rotation);
    }

    // Translate vertex position taking into account
    // quad center positions    
    const float4 quadCenterPosW = float4(input.mQuadCenterPosW, 0.0f);
    newVertexPosW += quadCenterPosW;

    // Update vertex in world and projection spaces
	output.mPosW = newVertexPosW.xyz;	
    output.mPosH = mul(newVertexPosW, gViewProj);
	
    // Update texture coordinates
    const float4 texC = float4(input.mTexC, 0.0f, 1.0f);
    output.mTexC = mul(texC, gTexMatrix).xy;
	
	return output;
}